/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package coalescent.is.cef.pui;

import cef.event.Event;
import cef.pui.EventConstructionException;
import cef.pui.EventImpl;
import cef.pui.pob.Builder;
import cef.pui.pob.BuilderException;
import coalescent.is.Samplers_K69;
import coalescent.is.cef.event.RunSamplers_Evt;
import coalescent.is.cef.pui.pob.Builders_IS;
import coalescent.is.cef.pui.pob.Samplers_Bldr;
import commons.core.ValueTypes;
import commons.is.Sampler;
import commons.util.ColorUtil;

import java.awt.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.List;

/**
 * Properties:
 * <ul>
 * <li>{@code coalescent.is.ISamplers.gt_EGT = true | false. If true, properties
 *         in } {@link coalescent.cef.pui.pob.Builders_Coa#of_AC_K69_GT_File(java.util.Properties, String)
 *         GeneTree} {@code and } {@link coalescent.cef.pui.pob.Builders_Coa#of_Model_K69(java.util.Properties, String)
 *         K69}
 * </li>
 * <li>{@code coalescent.is.ISamplers.gt_SD =
 *         true | false. If true, properties in } {@link coalescent.cef.pui.pob.Builders_Coa#of_AC_K69_GT_File(java.util.Properties, String)
 *         GeneTree} {@code and } {@link coalescent.cef.pui.pob.Builders_Coa#of_Model_K69(java.util.Properties, String)
 *         K69}
 * </li>
 * <li>{@code coalescent.is.ISamplers.argt_EGT =
 *         true | false. If true, properties in } {@link Builders#getARGeneTreeBuilder(java.util.Properties)
 *         ARGeneTree} {@code and } {@link coalescent.cef.pui.pob.Builders_Coa#of_Model_K69(java.util.Properties, String)
 *         K69}
 * </li>
 * <li>{@code coalescent.is.ISamplers.argt_EGT_cMap =
 *         true | false. If true, properties in } {@link Builders_IS#getARGeneTreeISBuilder(java.util.Properties)ARGeneTreeIS}
 *         {@code and } {@link coalescent.cef.pui.pob.Builders_Coa#of_Model_K69(java.util.Properties, String)
 *         K69}
 * </li>
 * <li>{@code coalescent.is.ISamplers.argt_SpougeSD =
 *         true | false. If true, properties in } {@link coalescent.cef.pui.pob.Builders_Coa#of_AC_K69_GT_File(java.util.Properties, String)
 *         GeneTree} {@code and } {@link coalescent.cef.pui.pob.Builders_Coa#of_Model_K69(java.util.Properties, String)
 *         K69}
 * </li>
 * <li>{@code coalescent.is.isWindowSize = integer }</li>
 * <li>{@code coalescent.is.updateFreq = integer }</li>
 * </ul>
 *
 * @author Susanta Tewari
 * @version version
 * @history Created on Jul 31, 2012.
 * @since since
 */
public final class RunSamplers_EvtImpl extends EventImpl implements RunSamplers_Evt {

    private final Builder<Integer> windowSize_b;
    private final Samplers_Bldr samplers_b;
    private final Builder<Integer> updateFreq_b;
    private BigDecimal exactValue;
    private Map<String, Color> colorMap;
    private Builder<ValueTypes.ColorMap> color_map_b;

    /**
     * @param props properties as specified in the class javadoc
     * @throws cef.pui.EventConstructionException if error in properties
     */
    public RunSamplers_EvtImpl(final Properties props) throws EventConstructionException {

        super(props);

        super.processEventProperties(getImplementedEventInterfaces());

        samplers_b = Builders_IS.of_SamplerS(props, "coalescent.is.ISamplers",
                "coalescent.builder.GeneTree");    // samplers
        windowSize_b = Builders_IS.getWindowSize(props, "coalescent.is.ISamplers");    // window size
        updateFreq_b = Builders_IS.getUpdateFreq(props, "coalescent.is.ISamplers");    // update freq
        color_map_b  = samplers_b.getColorMapBuilder();    // color map

        //J- exact prob (opt.)
        final Builder<BigDecimal> exact_prob_b = Builders_IS.getExactProb(props, "coalescent.is.ISamplers");
        if (exact_prob_b.canBuild()) exactValue = exact_prob_b.build();//J+

    }

    @Override
    protected List<Class<? extends Event>> getImplementedEventInterfaces() {

        final List<Class<? extends Event>> result = new ArrayList<>(2);

        result.add(RunSamplers_Evt.class);
        result.add(Event.class);

        return result;
    }

    @Override
    public Collection<Sampler<?>> getSamplers() throws BuilderException {
        return samplers_b.build();
    }

    @Override
    public GUI getGUISettings() {

        return new GUI() {

            @Override
            public boolean isExactValueKnown() {
                return exactValue != null;
            }
            @Override
            public BigDecimal getExactValue() {
                return exactValue;
            }
            @Override
            public boolean isISWindowSizeKnown() {
                return windowSize_b.canBuild();
            }
            @Override
            public int getISWindowSize() {
                return windowSize_b.build();
            }
            @Override
            public int getUpdateFreq() {
                return updateFreq_b.build();
            }
            @Override
            public Map<String, Color> getColorMap() {

                if (colorMap == null) {

                    List<String> color_labels = new ArrayList<>();

                    if (isExactValueKnown()) color_labels.add(Samplers_K69.EXACT);

                    for (Sampler<?> sampler : getSamplers()) {
                        color_labels.add(sampler.getName());
                    }

                    colorMap = ColorUtil.of_colorMap_dark(color_labels);

                    if (color_map_b.canBuild()) {    // override with user preferences

                        final Map<String, Color> map = color_map_b.build().getMap();

                        for (String key : map.keySet()) {
                            colorMap.put(key, map.get(key));
                        }
                    }
                }

                return colorMap;
            }
        };
    }
}
